﻿#region MIT Licence
/*
 * Copyright (C) 2014 PdfCreative
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom 
 * the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included 
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 
 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#endregion

using System;
using System.Collections.Generic;
using System.Text;

namespace PdfCreative.Pdf.Graphics.Tables
{
    /// <summary>
    /// The Cell class encapsulates all the information required to draw a table cell; its content and background,
    /// border details, merge information and text format.
    /// </summary>
    public class Cell
    {
        // Private fields
        // ==============
        #region Private fields
        private Brush _background;                      // The brush to paint the background of the cell with.
        private Pen _border;                            // The pen to draw the border with.
        private Borders _borders;                       // The borders of the cell.
        private StyledText _content;                    // The cell content.
        private MergeInformation _mergeInformation;     // The merge information (column and row spanning).
        private StringFormat _stringFormat;             // The string format for the cell content.
        #endregion



        // Public properties
        // =================
        #region Public properties
        /// <summary>
        /// Sets or retrieves the brush used to paint the cell background.
        /// A Null reference is allowed; cells with a Null background brush will
        /// have no background painted.
        /// </summary>
        public Brush Background
        {
            get { return _background; }
            set { _background = value; }
        }

        /// <summary>
        /// Sets or retrieves the pen used to paint the cell borders. A Null reference is
        /// allowed; cells with a Null border pen will have no borders drawn, regardless
        /// of the value of the Borders property.
        /// </summary>
        public Pen Border
        {
            get { return _border; }
            set { _border = value; }
        }

        /// <summary>
        /// Sets or retrieves a list of the borders that need to be drawn
        /// around the cell.
        /// </summary>
        public Borders Borders
        {
            get { return _borders; }
            set { _borders = value; }
        }

        /// <summary>
        /// Sets or retrieves the cell content.
        /// This value can be a Null reference; the cell not have any content
        /// drawn, but will still have its background painted and borders
        /// drawn if an appropriate brush and pen was supplied.
        /// </summary>
        public StyledText Content
        {
            get { return _content; }
            set { _content = value; }
        }

        /// <summary>
        /// Sets or retrieves the formatting information for the cell content.
        /// This value can be a Null reference; a default format will be applied to
        /// the cell contents in that case.
        /// </summary>
        public StringFormat Format
        {
            get { return _stringFormat; }
            set { _stringFormat = value; }
        }

        /// <summary>
        /// Sets or retrieves the merge information for the cell.
        /// </summary>
        public MergeInformation MergeInformation
        {
            get { return _mergeInformation; }
            set { _mergeInformation = value; }
        }
        #endregion



        // Public methods
        // ==============
        #region Public methods
        /// <summary>
        /// Appends styled inline text to this cell. This method returns the current
        /// Cell instance to allow chaining of statements.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns>The current Cell instance.</returns>
        public Cell Append(InlineText text)
        {
            this._content.Append(text);

            return this;
        }

        /// <summary>
        /// Appends styled inline text to this cell. This method returns the current
        /// Cell instance to allow chaining of statements.
        /// </summary>
        /// <param name="text">The content.</param>
        /// <param name="brush">The brush to draw the content with.</param>
        /// <param name="font">The font to draw the content in.</param>
        /// <param name="fontSize">The font size.</param>
        /// <returns>The current Cell instance.</returns>
        public Cell Append(string text, Brush brush, Font font, float fontSize)
        {
            this._content.Append(text, brush, font, fontSize);

            return this;
        }
        #endregion



        // Public constructors
        // ===================
        #region Public constructors

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="brush">The brush to draw the content with.</param>
        /// <param name="font">The content's font.</param>
        /// <param name="fontSize">The font size.</param>
        public Cell(string content, Brush brush, Font font, float fontSize)
        : this(content, brush, null, font, fontSize, MergeInformation.NoMerge, null, null, Borders.None) { }
        
        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="brush">The brush to draw the content with.</param>
        /// <param name="font">The content's font.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="merge">The merge information for the cell.</param>
        /// <param name="format">The format of the content. this argument can be a Null reference; a standard
        /// format will be provided.</param>
        public Cell(
            string content, 
            Brush brush,
            Font font,
            float fontSize,
            MergeInformation merge,
            StringFormat format)
        : this(content, brush, null, font, fontSize, merge, format, null, Borders.None) { }

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="brush">The brush to draw the content with.</param>
        /// <param name="background">The brush to paint the cell's background with. This argument can be a Null reference;
        /// in that case, the cell will have no background.</param>
        /// <param name="font">The content's font.</param>
        /// <param name="fontSize">The font size.</param>
        public Cell(
            string content,
            Brush brush,
            Brush background,
            Font font,
            float fontSize)
        : this(content, brush, background, font, fontSize, MergeInformation.NoMerge, null, null, Borders.None) { }

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="brush">The brush to draw the content with.</param>
        /// <param name="background">The brush to paint the cell's background with. This argument can be a Null reference;
        /// in that case, the cell will have no background.</param>
        /// <param name="font">The content's font.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="merge">The merge information for the cell.</param>
        /// <param name="format">The format of the content. this argument can be a Null reference; a standard
        /// format will be provided.</param>
        public Cell(
            string content,
            Brush brush, 
            Brush background, 
            Font font,
            float fontSize,
            MergeInformation merge,
            StringFormat format)
            : this(content, brush, background, font, fontSize, merge, format, null, Borders.None) { }

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="brush">The brush to draw the content with.</param>
        /// <param name="background">The brush to paint the cell's background with. This argument can be a Null reference;
        /// in that case, the cell will have no background.</param>
        /// <param name="font">The content's font.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="merge">The merge information for the cell.</param>
        /// <param name="format">The format of the content. this argument can be a Null reference; a standard
        /// format will be provided.</param>
        /// <param name="border">The pen to draw the border with. This argument can be a Null reference; the
        /// cell won't have a border in that case, regardless of the value of the Borders property.</param>
        /// <param name="borders">The cell's visible borders.</param>
        public Cell(
            string content,
            Brush brush,
            Brush background,
            Font font,
            float fontSize,
            MergeInformation merge,
            StringFormat format,
            Pen border,
            Borders borders)
        {
            // Create a new StyledText instance based on the
            // content, foreground brush and font information.
            if(false==String.IsNullOrEmpty(content))
                _content = new StyledText(content, brush, font, fontSize);
            
            _background = background;
            _border = border;
            _borders = borders;
            _stringFormat = format;
            _mergeInformation = merge;
        }

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The cell's content.</param>
        public Cell(StyledText content)
            : this(content, null, MergeInformation.NoMerge, null, null, Borders.None) { }

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The cell's content.</param>
        /// <param name="merge">The merge information for the cell.</param>
        /// <param name="format">The format of the content. this argument can be a Null reference; a standard
        /// format will be provided.</param>
        public Cell(
            StyledText content, 
            MergeInformation merge,
            StringFormat format)
            : this(content, null, merge, format, null, Borders.None) { }

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The cell's content.</param>
        /// <param name="background">The brush to paint the cell's background with. This argument can be a Null reference;
        /// in that case, the cell will have no background.</param>
        public Cell(
            StyledText content, 
            Brush background)
            : this(content, background, MergeInformation.NoMerge, null, null, Borders.None) { }

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The cell's content.</param>
        /// <param name="background">The brush to paint the cell's background with. This argument can be a Null reference;
        /// in that case, the cell will have no background.</param>
        /// <param name="merge">The merge information for the cell.</param>
        /// <param name="format">The format of the content. this argument can be a Null reference; a standard
        /// format will be provided.</param>
        public Cell(
            StyledText content, 
            Brush background, 
            MergeInformation merge,
            StringFormat format) 
            : this(content, background, merge, format, null, Borders.None) { }

        /// <summary>
        /// Constructs a new Cell instance.
        /// </summary>
        /// <param name="content">The cell's content.</param>
        /// <param name="background">The brush to paint the cell's background with. This argument can be a Null reference;
        /// in that case, the cell will have no background.</param>
        /// <param name="merge">The merge information for the cell.</param>
        /// <param name="format">The format of the content. this argument can be a Null reference; a standard
        /// format will be provided.</param>
        /// <param name="border">The pen to draw the border with. This argument can be a Null reference; the
        /// cell won't have a border in that case, regardless of the value of the Borders property.</param>
        /// <param name="borders">The cell's visible borders.</param>
        public Cell(
            StyledText content,
            Brush background, 
            MergeInformation merge,
            StringFormat format,
            Pen border, 
            Borders borders)
        {
            _background = background;
            _border = border;
            _borders = borders;
            _content = content;
            _stringFormat = format;
            _mergeInformation = merge;
        }

        #endregion
    }
}
